// License: http://www.codeplex.com/entlibcontrib/Project/License.aspx
// Author: Randy

using System;
using System.Globalization;

namespace EntLibContrib.Logging.Parser
{
    /// <summary>
    /// Encapsulates the logic for parsing the time stamp text from a log file.
    /// </summary>
    public class TimeStampParserFraction : ITimeStampParser
    {
        public const string TimeStampFormat = "o";

        /// <summary>
        /// Constructor to initialize a new instance of the class.
        /// Sets <see cref="FormatProvider"/> to <see cref="CultureInfo.CurrentCulture"/>,
        /// which is used in <see cref="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TimeStampToken.FormatToken"/>.
        /// </summary>
        public TimeStampParserFraction()
        {
            this.formatProvider = CultureInfo.CurrentCulture;
        }

        /// <summary>
        /// Constructor to initialize a new instance of the class.
        /// </summary>
        /// <param name="formatProvider">time stamp format provider for month-day or day-month order, etc.</param>
        public TimeStampParserFraction(IFormatProvider formatProvider)
        {
            this.formatProvider = formatProvider;
        }

        private IFormatProvider formatProvider;
        /// <summary>
        /// Specify time stamp format for month-day or day-month order, etc.
        /// </summary>
        public IFormatProvider FormatProvider
        {
            get { return formatProvider; }
            set { formatProvider = value; }
        }

        /// <summary>
        /// Parse the time stamp text from a log file.
        /// </summary>
        /// <param name="stringTime">time stamp text</param>
        /// <returns>date and time</returns>
        public DateTime ParseTimeStamp(string stringTime)
        {
            //return DateTime.ParseExact(stringTime, TimeStampFormat, formatProvider).ToUniversalTime();
            //was slow (even slower than DateTime.Parse, which is slower than DateTime.ParseExact)
            //FractionTimeStamp elapsed seconds = 1.107
            //DefaultTimeStamp elapsed seconds = 1.065
            //FormatTimeStamp elapsed seconds = 1.062
            //new DateTime(int.Parse is faster than the others
            //FractionTimeStamp elapsed seconds = 1.039

            // 0    0  0  1  1  1  2
            // 01234567890123456789012
            // yyyy-MM-ddTHH:mm:ss.fff
            string substring;
            substring = stringTime.Substring(00, 4);
            int y = int.Parse(substring);
            substring = stringTime.Substring(05, 2);
            int M = int.Parse(substring);
            substring = stringTime.Substring(08, 2);
            int d = int.Parse(substring);
            substring = stringTime.Substring(11, 2);
            int H = int.Parse(substring);
            substring = stringTime.Substring(14, 2);
            int m = int.Parse(substring);
            substring = stringTime.Substring(17, 2);
            int s = int.Parse(substring);
            substring = stringTime.Substring(20, 3);
            int f = int.Parse(substring);
            return new DateTime(y, M, d, H, m, s, f);
        }
    }
}
